--------------------------------------------
FPS Mod
Reference Guide
by TheEpigoni
--------------------------------------------

This will be done by catergories in a sortof mishmash of explanations, but at least they'll be in order.

--------------------------------------------
Custom Script Code
--------------------------------------------

- GetHeight
This function takes in a location and returns a real which directly represents that location's terrain height. 
I'll start from the beggining since this is the easiest way for me to do it. 

Okay everything began with a conversation I had with one only known as Ari when he was telling me that he had come up with a way to 
read height in game. Well, lo and behold I got interested and he went on to explain to me how he extracted 
the w3e file from a map that he had and then using Zepirs tutorial figured out what meant what and realized 
basically that the whole w3e file was simply a list of points (in this case gridpoints) that represent the 
gridpoints that make up the terrain of any warcraft 3 map. He then went on about an explanataion of how 
it worked and some basic triggers which ingame found the nearest gridpoint to a unit and displayed that 
gridpoints height as the units height. 

Well this wasn't enough for me so I set out to do my own thing. Although I have to say without Ari's ideas
I never would have had anything in the first place. And so I started by learning a little bit about w3e files, then 
some more about binary files, and poof came the w3e reader. A program which 
reads in the w3e and prints out a piece of code, which will stores the heights of every gridpoint on a map, into 
an array which can then be read. (This is the already known Initialize Height Variables trigger). Then I followed 
that up witht the GetHeigh function which takes in a location, reads the array, and pops out the exact height of
the unit. 

Simple...yeah, damn I'm actually going to have to explain this now. Okay well we start off with a 
shitload of local variables, then a simple test to see if the location is actually inside the playable map area (if 
not it returns 9999 as the height indicating a giant wall) then what we do is we get the X coordinate of the 
location we were sent, and use that with a little rounding and dividing by 128 (the size of a tile) to figure out the
x location (from 0 to 32 on a 32x32 map) of the grid box our location is in, then we repeat with y. Basically 
what we're doing is figuring out the top left corner of the grid box we are analysing and setting it's coordinates 
to tilex and tiley. 

Then we set xdist and ydist to remember how far away from the lower left corner of the gridbox 
our actual location is. Continuing on we simply use our tile information to extract from the array the proper values 
we need. (The array is an array of strings, where every 5 characters is another value). Then once we have the 
heights, we store the heights of each corner surrounding the gridbox that the location is in. 

Then the program simply takes the x slope of the left or right side and applies it to the xdist we stored before, and the y slope of 
the top or bottom side and applies it to the ydist we stored before to find out the exact height. (Top or Bottom 
and Left or Right sides are determined by whether the location is in the bottom left of the grid box or top right).

Sorry for the sloppy description but I lazied out because I saw I had plenty of comments within the code and you 
don't necessarily need to know this much about a function you most likely won't be changing.

- Getslope
I won't explain how this function works because I personally don't remember how, I would if I looked back at the 
code but I really don't want too. I'm mostly sick of doing so much trig work and I don't want to see it anymore. 
But the basics of the function are as follows, it inputs a location and outputs the slope of your movement if the 
"move" variable is set to true, or the slope of the angle you are facing if move is set to false.

- UpdateMultiboards
A typical updatemultiboards function, written by KaTTaNa. Very standard nothing to explain.

- CamZAdjust
This is a very crucial function which was necessary due to a smoothing technique that blizzard uses in everything 
they do, in this case it involved camera settings. Basically what was happening was that the height of the terrain 
was being smoothed into the camera height, so the camera was constantly off. To counteract this I created this 
function to adjust the height of the camera to accomodate for this. Basically it adjusts the Camera ZOFFSET not 
to the actual height, but to the different of height between the new position and the old one. Anyways it fixes the 
problem and that's all I really cared about.

--------------------------------------------
Initialization
--------------------------------------------

- Initialize Variables
All very standard stuff, everythine that MoveCnt initializes is basically useless past movecnt[10] so you can erase it, 
but I didn't since I'm a lazy bum. Everything else is sortof self explanitory except for the custom jumpheight script. 
What that does is set whatever the inital height of the marine is as the sortof ground level comparison height that 
it uses to do all jump calculations. It's not important what the height is as long as it has a sortof anchor point from 
which to do all other calculations for jumping.

- Initialize Height Variables
This is just the initialization for the array that GetHeight and GetSlope use.

--------------------------------------------
Camera
--------------------------------------------

- Setup Camera
Just some basic camera initailizations

- FPV Camera
First Person View camera settings

- TPV Camera
Third Person View camera settings

--------------------------------------------
Controls
--------------------------------------------

- Clear Selection
Clears anything the player may accidently select while adventuring so you don't 
give out some random attack or more orders to your marine.

- Fire
The fire trigger is a bit complicated, the first thing to know is that it can be either run once 
or turned on for a periodic run machine gun style. The second, is that it's a linear trace that 
ends when the bullet is "underground", since any warcraft map is simply a warped plane made
out of many gridpoints, it's sortof like a blanket that's been thrown over a few chairs, therefore
if you ever go under the blanket, the only way to do it is to go through it which implies a collision, 
hence our collision detection system.

Now the rest is simple, it takes the inital variables of location, facing, angle of attack + 5 (not sure 
why +5 but it fixes an innacuracy in firing that somehow appeared, this may have something to do 
with mapsize, I really never found out), and then it just loops until the height of the bullet is less than 
the height of the ground and then does a little impact. Now the important part comes in the itteration 
of movements, there are a few things that can be changed here to save up cpu ussage which is very 
precious specifically there's the polar projection (how far the unit moves every iteration) the modulo of
 i (how often it checks for surrounding units it might have hit) and the 10.0 * Tan(...) which you have to 
mach with the ammount in the polar projection.

After that there's the simple checkhit function which scans around the bullet to check for targets and then 
checks the height of the target to make sure the bullet didn't go above or under them (assumes that 120 
is the averge height of all things that can be fired at), then just does damage on impact sprays some blood 
or does a rifleimpact special effect if it hits ground.

- FireGrenade
I'll leave this up to you to figure out since it doesn't work, which is why it's disabled in the movement trigger, 
but anyways it needs fixing and I gave up on it. I won't explain it because if I have to explain it then you won't be able to fix it.

- MoveCntRead
This function should be left alone, this is the function that constantly reads MoveCnt (the interface array, the 
one that the control program changes) and then accordingly runs functions changes variables or whatnot. It
 is also pretty well commented, so figure it out yourselves.

- Movements
This is the heart of the whole engine...well not really but still. Here is done everything that reacts to what 
MoveCnt does, the beggining code is written by Stoned but it basically runs all the mouse movement stuff 
and it's best to be left alone since it works and it works well. Now the rest is the fun part. First come the 
simple if's to run either the fpv or tpv cameras, then CamZAdjust is run to fix the rounding/smoothing problem. 
Then come some simple ifs to test if the right mouse button is down or the left mouse button and what weapon
is selected for jumping and firing. Finally old mouse states are set to make sure you can't for instance 
hold the button down when firing a pistol.

--------------------------------------------
Console
--------------------------------------------

- This is all self explanatory text input stuff

--------------------------------------------
Debug
--------------------------------------------

- Self explanatory debug text display stuff

--------------------------------------------
Movement
--------------------------------------------

- Jump
This is a very important function that handles all the Z coordinate movements of the engine. It 
covers two things, air movement, and parting with the ground. Air movement is done easily enough
 by simply applying a constant gravity every second and then once again applying a changing ZVelocity 
to the units jumpheigh, which then accordingly changes the units fly height. It's all simple really =). 

I really don't want to explain this partially out of laziness but mostly because if you yourself can't figure it out, 
then you shouldn't be screwing with this function. And I will leave you with that.

- Update Position
This is the second heart of the engine, this is what applies all the xy velocity and friction and everything 
else changes. Although I won't be as much of a bastard as I was with the jump function, once again if 
you don't understand it yourself, don't screw with it, the global variables should be enough for you. As 
for the rest of you, first we start by calculating the x and y max velocities, this is used later. Then we 
have a quick check to make sure the player isn't standing still. If the player is moving, we then calculate
x and y friction, and apply it positively or negatively depending on whether the speed is positive or negative. 

Repeat the same for y friction. Then we check if either of the frictions overran their limit and actually reversed 
the velocity from positive to negative, in which case we cut them off and set them to 0, then set the cutoff 
boolean to 0. 

Then we check if either the x or y was cut off and if not, we actually apply the friction to the 
velocity. Then we apply the maximums and cut off the velocities if the acceleration has placed them above 
the globally set maximums. Then we do a quick caluculation to make sure if the unit is on the ground and if 
it is we check to see if it isn't going up a slope that is too steep, if it is we set velocity to 0. And then finally 
after all this we apply the velocity to the actual position of the unit.

- Foreward, Backward, Strafe Left, Strafe Right
This simple functions just use a little trigonometry to alter the x and y velocities properly applying the XYAccel 
that was globally set to represent what acceleration is applied if you hold down any of those keys.

--------------------------------------------
Multiboards
--------------------------------------------

- These are standard multiboard triggers written by KaTTaNa.

--------------------------------------------
Copyright 2002-2004 The FPS Mod Team & Warcraft III Campaigns. 
All Rights Reserved. Warcraft III is the property of Blizzard Entertainment.
--------------------------------------------